package com.github.m6d21.sso.business.controller.login;

import static com.github.m6d21.sso.support.enums.StatusCode.LOGIN_ERROR;

import com.github.m6d21.sso.core.exception.BusinessException;
import com.github.m6d21.sso.core.exception.LoginException;
import com.github.m6d21.sso.model.user.entity.User;
import com.github.m6d21.sso.model.user.vo.UserVO;
import com.github.m6d21.sso.service.login.ILoginService;
import com.github.m6d21.sso.support.enums.StatusCode;
import com.github.m6d21.sso.support.model.Response;
import com.github.m6d21.sso.support.session.SsoSessionHolder;
import com.github.m6d21.sso.support.util.ResponseUtil;
import com.github.m6d21.sso.support.validator.password.Password;
import com.github.m6d21.sso.support.validator.password.PasswordConstant;
import com.github.m6d21.sso.support.validator.password.PasswordConstant.Type;
import com.github.m6d21.sso.support.validator.phone.Phone;
import com.google.common.collect.Maps;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import java.util.Map;
import java.util.Optional;
import javax.annotation.Resource;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

/**
 *<p>
 *账号api
 *</p>
 *
 * @author liuyang
 * @date 2018-12-07 Fri 13:27:00
 * @since 1.0.0
 */
@Api(value = "login", description = "登录api")
@Validated
@RestController
@RequestMapping("/web")
public class LoginController {

    private static final Logger LOG = LoggerFactory.getLogger(LoginController.class);

    @Resource
    private ILoginService loginService;

    @ApiOperation(value = "登录接口", httpMethod = "POST")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "username", value = "用户名", paramType = "query", dataType = "string"),
        @ApiImplicitParam(name = "password", value = "密码", paramType = "query", dataType = "string"),
    })
    @PostMapping("/login")
    @ResponseBody
    public Response login
        (@NotNull(message = "用户名不能为空") @RequestParam("username") String username,
            @NotNull(message = "密码不能是空") @RequestParam("password") String password) {
        return loginForToken(username, password);
    }

    @ApiOperation(value = "登录接口(返回用户信息)", httpMethod = "POST")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "username", value = "用户名", paramType = "query", dataType = "string"),
        @ApiImplicitParam(name = "password", value = "密码", paramType = "query", dataType = "string"),
    })
    @PostMapping("/login/for/user")
    @ResponseBody
    public Response loginForUser
        (@NotNull(message = "用户名不能为空") @RequestParam("username") String username,
            @NotNull(message = "密码不能是空") @RequestParam("password") String password) {
        User user = loginService.login(username, password);
        Optional.of(user).orElseThrow(() -> new LoginException(400, "no"));
        if (user == null) {
            return ResponseUtil.fail(LOGIN_ERROR.getCode(), "用户名或密码错误");
        }
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        return ResponseUtil.success(userVO);
    }

    @ApiOperation(value = "登录接口(返回token)", httpMethod = "POST")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "username", value = "用户名", paramType = "query", dataType = "string"),
        @ApiImplicitParam(name = "password", value = "密码", paramType = "query", dataType = "string"),
    })
    @PostMapping("/login/for/token")
    @ResponseBody
    public Response loginForToken
        (@NotNull(message = "用户名不能为空") @RequestParam("username") String username,
            @NotNull(message = "密码不能是空") @RequestParam("password") String password) {
        User user = loginService.login(username, password);
        if (user == null) {
            return ResponseUtil.fail(LOGIN_ERROR.getCode(), "用户名或密码错误");
        }
        Map<String, Object> token = Maps.newHashMap();
        token.put("token", SsoSessionHolder.getToken());
        return ResponseUtil.success(token);
    }

    @ApiOperation(value = "退出登录", httpMethod = "POST")
    @PostMapping("/logout")
    @ResponseBody
    public Response logout() {
        loginService.logout();
        return ResponseUtil.success();
    }

    @ApiOperation(value = "用户注册", httpMethod = "POST")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "username", value = "用户名", paramType = "query", dataType = "string"),
        @ApiImplicitParam(name = "displayName", value = "昵称", paramType = "query", dataType = "string"),
        @ApiImplicitParam(name = "password", value = "密码", paramType = "query", dataType = "string"),
        @ApiImplicitParam(name = "repeatPassword", value = "确认密码", paramType = "query", dataType = "string"),
        @ApiImplicitParam(name = "phone", value = "手机号", paramType = "query", dataType = "string"),
        @ApiImplicitParam(name = "email", value = "邮箱", paramType = "query", dataType = "string")})
    @PostMapping("/register")
    @ResponseBody
    public Response<Integer> register(
        @NotBlank(message = "用户名不能为空") @RequestParam("username") String username,
        @NotBlank(message = "昵称不能为空") @RequestParam("displayName") String displayName,
        @NotBlank(message = "密码不能为空") @Password(message = PasswordConstant.SIMPLE_TIP, type = Type.SIMPLE) @RequestParam("password") String password,
        @NotBlank(message = "密码不能为空") @RequestParam("repeatPassword") String repeatPassword,
        @NotBlank(message = "邮箱不能为空") @Email(message = "邮箱格式不正确") @RequestParam("email") String email,
        @NotBlank(message = "手机号不能为空") @Phone @RequestParam("phone") String phone) {
        if(!password.equals(repeatPassword)){
            throw new BusinessException(StatusCode.FAIL.getCode(), "两次输入密码不一致");
        }
        User user = new User();
        user.setUsername(username);
        user.setDisplayName(displayName);
        user.setPassword(password);
        user.setEmail(email);
        user.setPhone(phone);
        user.setOperator(SsoSessionHolder.getDisplayName());
        Boolean success=loginService.register(user);
        if(!success){
            return ResponseUtil.fail(StatusCode.FAIL.getCode(),"注册失败");
        }
        return ResponseUtil.success();
    }

}
